<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深入理解React Hooks的工作原理 - TechBlog</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css">
    <style>
        :root {
            /* 亮色主题变量 */
            --bg-color: #ffffff;
            --text-color: #24292f;
            --border-color: #d0d7de;
            --card-bg: #f6f8fa;
            --header-bg: #f6f8fa;
            --accent-color: #0969da;
            --accent-hover: #0550ae;
            --code-bg: rgba(175, 184, 193, 0.2);
            --shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
            --tag-bg: #ddf4ff;
            --tag-color: #0969da;
            --filter-bg: #f6f8fa;
            --input-bg: #ffffff;
            --toc-bg: #f6f8fa;
            --progress-color: #0969da;
            --toc-active-bg: rgba(9, 105, 218, 0.1);
            --toc-active-border: #0969da;
        }

        .dark-theme {
            /* 深色主题变量 */
            --bg-color: #0d1117;
            --text-color: #e6edf3;
            --border-color: #30363d;
            --card-bg: #161b22;
            --header-bg: #161b22;
            --accent-color: #2f81f7;
            --accent-hover: #1c6bdb;
            --code-bg: rgba(110, 118, 129, 0.4);
            --shadow: 0 1px 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.7);
            --tag-bg: #388bfd26;
            --tag-color: #58a6ff;
            --filter-bg: #161b22;
            --input-bg: #0d1117;
            --toc-bg: #161b22;
            --progress-color: #2f81f7;
            --toc-active-bg: rgba(47, 129, 247, 0.15);
            --toc-active-border: #2f81f7;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-color);
            line-height: 1.6;
        }

        .container {
            max-width: 1280px;
            margin: 0 auto;
            padding: 0 20px;
        }

        /* 头部导航 */
        header {
            background-color: var(--header-bg);
            border-bottom: 1px solid var(--border-color);
            position: sticky;
            top: 0;
            z-index: 100;
        }

        .navbar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 16px 0;
            position: relative;
        }

        .logo {
            display: flex;
            align-items: center;
            gap: 10px;
            font-weight: 600;
            font-size: 20px;
            color: var(--text-color);
            text-decoration: none;
            z-index: 101;
        }

        .logo i {
            color: var(--accent-color);
        }

        .nav-links {
            display: flex;
            gap: 24px;
        }

        .nav-links a {
            color: var(--text-color);
            text-decoration: none;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.2s ease;
        }

        .nav-links a:hover {
            color: var(--accent-color);
        }

        .nav-links a.active {
            color: var(--accent-color);
            font-weight: 600;
        }

        .nav-actions {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .theme-toggle {
            background: none;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            padding: 8px 12px;
            color: var(--text-color);
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 14px;
            transition: all 0.2s ease;
        }

        .theme-toggle:hover {
            background-color: var(--code-bg);
        }

        .mobile-menu {
            display: none;
            background: none;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            color: var(--text-color);
            cursor: pointer;
            padding: 8px 12px;
            font-size: 16px;
            transition: all 0.2s ease;
        }

        .mobile-menu:hover {
            background-color: var(--code-bg);
        }

        /* 阅读进度条 */
        .reading-progress {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 3px;
            background: transparent;
            z-index: 99;
        }

        .reading-progress-bar {
            height: 100%;
            background: var(--progress-color);
            width: 0%;
            transition: width 0.2s ease;
        }

        /* 主要内容区域 */
        .main-content {
            display: flex;
            flex-direction: column;
            gap: 24px;
            padding: 32px 0;
        }

        /* 文章头部区域 */
        .article-header {
            margin-bottom: 16px;
        }

        .article-title {
            font-size: 32px;
            font-weight: 700;
            margin-bottom: 16px;
            line-height: 1.3;
        }

        .article-meta {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
            font-size: 14px;
            color: var(--text-color);
            opacity: 0.8;
            flex-wrap: wrap;
        }

        .article-tags {
            display: flex;
            gap: 8px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }

        .tag {
            background-color: var(--tag-bg);
            color: var(--tag-color);
            padding: 4px 10px;
            border-radius: 12px;
            font-size: 12px;
            font-weight: 500;
        }

        /* 内容容器 */
        .content-container {
            display: flex;
            gap: 32px;
            align-items: flex-start;
        }

        /* 文章内容区域 */
        .article-content {
            flex: 1;
            min-width: 0;
            background-color: var(--card-bg);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            padding: 32px;
        }

        /* 文章正文样式 */
        .article-body {
            font-size: 16px;
            line-height: 1.7;
        }

        .article-body h2 {
            font-size: 24px;
            font-weight: 600;
            margin: 32px 0 16px;
            padding-bottom: 8px;
            border-bottom: 1px solid var(--border-color);
        }

        .article-body h3 {
            font-size: 20px;
            font-weight: 600;
            margin: 24px 0 12px;
        }

        .article-body p {
            margin-bottom: 16px;
        }

        .article-body ul,
        .article-body ol {
            margin-bottom: 16px;
            padding-left: 24px;
        }

        .article-body li {
            margin-bottom: 8px;
        }

        .article-body blockquote {
            border-left: 4px solid var(--accent-color);
            padding-left: 16px;
            margin: 20px 0;
            font-style: italic;
            background-color: var(--code-bg);
            padding: 16px;
            border-radius: 0 6px 6px 0;
        }

        /* 修改深色模式代码块样式 */
        .dark-theme .article-body pre {
            background-color: #0d1117;
        }

        .article-body pre {
            background-color: var(--code-bg);
            border-radius: 6px;
            padding: 16px;
            overflow-x: auto;
            margin: 20px 0;
            font-size: 14px;
            border: 1px solid var(--border-color);
        }

        .article-body code {
            font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
            background-color: var(--code-bg);
            padding: 2px 6px;
            border-radius: 4px;
            font-size: 14px;
        }

        .article-body pre code {
            background: none;
            padding: 0;
        }

        .article-body img {
            max-width: 100%;
            height: auto;
            border-radius: 6px;
            margin: 20px 0;
            border: 1px solid var(--border-color);
        }

        .article-body table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }

        .article-body th,
        .article-body td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid var(--border-color);
        }

        .article-body th {
            background-color: var(--code-bg);
            font-weight: 600;
        }

        /* 文章导航 */
        .article-navigation {
            display: flex;
            justify-content: space-between;
            margin-top: 40px;
            padding-top: 20px;
            border-top: 1px solid var(--border-color);
        }

        .nav-btn {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 10px 16px;
            background-color: var(--code-bg);
            color: var(--text-color);
            text-decoration: none;
            border-radius: 6px;
            transition: all 0.2s ease;
            max-width: 45%;
        }

        .nav-btn:hover {
            background-color: var(--accent-color);
            color: white;
        }

        .nav-btn.prev {
            text-align: left;
        }

        .nav-btn.next {
            text-align: right;
            margin-left: auto;
        }

        /* 目录区域 - 优化样式 */
        .toc-container {
            width: 280px;
            flex-shrink: 0;
            position: sticky;
            top: 100px;
            max-height: calc(100vh - 140px);
            overflow-y: auto;
        }

        .toc-card {
            background-color: var(--card-bg);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            padding: 20px;
        }

        .toc-title {
            font-size: 16px;
            font-weight: 600;
            margin-bottom: 16px;
            padding-bottom: 8px;
            border-bottom: 1px solid var(--border-color);
        }

        .toc-list {
            list-style: none;
        }

        .toc-item {
            margin-bottom: 8px;
            position: relative;
        }

        .toc-link {
            color: var(--text-color);
            text-decoration: none;
            font-size: 14px;
            transition: all 0.3s ease;
            display: block;
            padding: 8px 12px;
            border-radius: 4px;
            border-left: 3px solid transparent;
            position: relative;
            overflow: hidden;
        }

        .toc-link::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, var(--toc-active-bg), transparent);
            transition: left 0.5s ease;
        }

        .toc-link:hover {
            background-color: var(--toc-active-bg);
            color: var(--accent-color);
            border-left-color: var(--accent-color);
        }

        .toc-link.active {
            background-color: var(--toc-active-bg);
            color: var(--accent-color);
            font-weight: 600;
            border-left-color: var(--toc-active-border);
            transform: translateX(5px);
        }

        .toc-link.active::before {
            left: 100%;
        }

        .toc-sublist {
            list-style: none;
            padding-left: 16px;
            margin-top: 4px;
        }

        .toc-sublist .toc-link {
            font-size: 13px;
            padding: 6px 12px;
        }

        /* 相关文章 */
        .related-articles {
            margin-top: 40px;
        }

        .section-title {
            font-size: 24px;
            font-weight: 600;
            margin-bottom: 20px;
            padding-bottom: 12px;
            border-bottom: 1px solid var(--border-color);
        }

        .related-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 20px;
        }

        .related-card {
            background-color: var(--card-bg);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            padding: 20px;
            transition: border-color 0.2s ease;
        }

        .related-card:hover {
            border-color: var(--accent-color);
        }

        .related-title {
            font-size: 18px;
            font-weight: 600;
            margin-bottom: 8px;
        }

        .related-title a {
            color: var(--accent-color);
            text-decoration: none;
        }

        .related-title a:hover {
            text-decoration: underline;
        }

        .related-meta {
            display: flex;
            gap: 12px;
            margin-bottom: 12px;
            font-size: 13px;
            opacity: 0.8;
        }

        .related-excerpt {
            font-size: 14px;
            line-height: 1.5;
        }

        /* 文章操作栏 */
        .article-actions {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 30px 0;
            padding: 16px;
            background-color: var(--filter-bg);
            border: 1px solid var(--border-color);
            border-radius: 6px;
        }

        .action-buttons {
            display: flex;
            gap: 12px;
        }

        .action-btn {
            display: flex;
            align-items: center;
            gap: 6px;
            padding: 8px 16px;
            background-color: var(--code-bg);
            color: var(--text-color);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.2s ease;
            font-size: 14px;
        }

        .action-btn:hover {
            background-color: var(--accent-color);
            color: white;
            border-color: var(--accent-color);
        }

        .action-btn.liked,
        .action-btn.bookmarked {
            background-color: var(--accent-color);
            color: white;
            border-color: var(--accent-color);
        }

        .share-options {
            display: flex;
            gap: 8px;
        }

        .share-btn {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 36px;
            height: 36px;
            border-radius: 50%;
            background-color: var(--code-bg);
            color: var(--text-color);
            border: none;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .share-btn:hover {
            background-color: var(--accent-color);
            color: white;
        }

        /* 页脚 */
        footer {
            border-top: 1px solid var(--border-color);
            padding: 32px 0;
            text-align: center;
            font-size: 14px;
            color: var(--text-color);
            opacity: 0.8;
        }

        /* 添加GitHub深色主题的代码高亮样式 */
        .dark-theme .hljs {
            color: #c9d1d9;
            background: #0d1117;
        }

        .dark-theme .hljs-doctag,
        .dark-theme .hljs-keyword,
        .dark-theme .hljs-meta .hljs-keyword,
        .dark-theme .hljs-template-tag,
        .dark-theme .hljs-template-variable,
        .dark-theme .hljs-type,
        .dark-theme .hljs-variable.language_ {
            color: #ff7b72;
        }

        .dark-theme .hljs-title,
        .dark-theme .hljs-title.class_,
        .dark-theme .hljs-title.class_.inherited__,
        .dark-theme .hljs-title.function_ {
            color: #d2a8ff;
        }

        .dark-theme .hljs-attr,
        .dark-theme .hljs-attribute,
        .dark-theme .hljs-literal,
        .dark-theme .hljs-meta,
        .dark-theme .hljs-number,
        .dark-theme .hljs-operator,
        .dark-theme .hljs-variable,
        .dark-theme .hljs-selector-attr,
        .dark-theme .hljs-selector-class,
        .dark-theme .hljs-selector-id {
            color: #79c0ff;
        }

        .dark-theme .hljs-regexp,
        .dark-theme .hljs-string,
        .dark-theme .hljs-meta .hljs-string {
            color: #a5d6ff;
        }

        .dark-theme .hljs-built_in,
        .dark-theme .hljs-symbol {
            color: #ffa657;
        }

        .dark-theme .hljs-comment,
        .dark-theme .hljs-code,
        .dark-theme .hljs-formula {
            color: #8b949e;
        }

        .dark-theme .hljs-name,
        .dark-theme .hljs-quote,
        .dark-theme .hljs-selector-tag,
        .dark-theme .hljs-selector-pseudo {
            color: #7ee787;
        }

        .dark-theme .hljs-subst {
            color: #c9d1d9;
        }

        .dark-theme .hljs-section {
            color: #1f6feb;
            font-weight: bold;
        }

        .dark-theme .hljs-bullet {
            color: #f2cc60;
        }

        .dark-theme .hljs-emphasis {
            color: #c9d1d9;
            font-style: italic;
        }

        .dark-theme .hljs-strong {
            color: #c9d1d9;
            font-weight: bold;
        }

        .dark-theme .hljs-addition {
            color: #aff5b4;
            background-color: #033a16;
        }

        .dark-theme .hljs-deletion {
            color: #ffdcd7;
            background-color: #67060c;
        }

        /* 响应式设计优化 */
        @media (max-width: 1024px) {
            .content-container {
                gap: 24px;
            }

            .toc-container {
                width: 250px;
            }
        }

        @media (max-width: 900px) {
            .content-container {
                flex-direction: column;
            }

            .toc-container {
                width: 100%;
                order: -1;
                margin-bottom: 24px;
                position: static;
            }

            .toc-card {
                padding: 16px;
            }
        }

        @media (max-width: 768px) {
            .container {
                padding: 0 16px;
            }

            .navbar {
                padding: 12px 0;
            }

            .logo {
                font-size: 18px;
            }

            .nav-links {
                position: absolute;
                top: 100%;
                left: 0;
                width: 100%;
                background-color: var(--header-bg);
                border-top: 1px solid var(--border-color);
                flex-direction: column;
                padding: 16px 20px;
                display: none;
                box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            }

            .nav-links.active {
                display: flex;
            }

            .nav-links a {
                padding: 12px 0;
                border-bottom: 1px solid var(--border-color);
                font-size: 16px;
            }

            .nav-links a:last-child {
                border-bottom: none;
            }

            .mobile-menu {
                display: block;
                min-height: 44px;
                min-width: 44px;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            .theme-toggle,
            .mobile-menu {
                padding: 10px 14px;
            }

            .main-content {
                padding: 24px 0;
                gap: 20px;
            }

            .content-container {
                gap: 20px;
            }

            .article-title {
                font-size: 24px;
            }

            .article-content {
                padding: 20px;
                overflow: hidden;
                width: 100%;
                max-width: 100%;
            }

            .article-body {
                font-size: 15px;
                max-width: 100%;
                overflow-x: hidden;
                word-wrap: break-word;
            }

            .article-body h2 {
                font-size: 20px;
            }

            .article-body h3 {
                font-size: 18px;
            }

            .article-meta {
                flex-direction: column;
                gap: 8px;
            }

            .article-actions {
                flex-direction: column;
                gap: 16px;
                align-items: stretch;
            }

            .action-buttons {
                justify-content: center;
            }

            .share-options {
                justify-content: center;
            }

            .related-grid {
                grid-template-columns: 1fr;
            }

            /* 修改文章导航为垂直布局 */
            .article-navigation {
                flex-direction: column;
                gap: 12px;
                margin-top: 32px;
                padding-top: 20px;
            }

            .nav-btn {
                max-width: 100%;
                width: 100%;
                justify-content: center;
                text-align: center;
                padding: 12px 16px;
            }

            .nav-btn.prev {
                text-align: center;
                order: 1;
            }

            .nav-btn.next {
                text-align: center;
                margin-left: 0;
                order: 2;
            }

            /* 调整按钮内图标位置 */
            .nav-btn.prev i {
                order: 1;
                margin-right: 8px;
            }

            .nav-btn.prev span {
                order: 2;
            }

            .nav-btn.next i {
                order: 2;
                margin-left: 8px;
            }

            .nav-btn.next span {
                order: 1;
            }

            /* 文本内容自动换行 */
            .article-body p,
            .article-body li,
            .article-body blockquote,
            .article-body h2,
            .article-body h3 {
                word-wrap: break-word;
                overflow-wrap: break-word;
                hyphens: auto;
            }

            /* 代码块保持横向滚动 */
            .article-body pre {
                overflow-x: auto;
                max-width: 100%;
                font-size: 13px;
                padding: 12px;
                -webkit-overflow-scrolling: touch;
            }

            /* 表格横向滚动 */
            .article-body table {
                display: block;
                overflow-x: auto;
                white-space: nowrap;
                max-width: 100%;
            }

            /* 图片限制宽度 */
            .article-body img {
                max-width: 100%;
                height: auto;
            }

            /* 减少移动端的动画效果 */
            * {
                transition: none;
            }

            /* 保留必要的过渡 */
            .theme-toggle,
            .mobile-menu,
            .nav-links a,
            .action-btn,
            .share-btn,
            .nav-btn {
                transition: all 0.2s ease;
            }

            /* 移动端目录样式优化 */
            .toc-link {
                padding: 10px 12px;
            }
        }

        @media (max-width: 480px) {
            .article-tags {
                gap: 6px;
            }

            .container {
                padding: 0 12px;
            }

            .content-container {
                gap: 16px;
            }

            /* 小屏幕下的导航按钮优化 */
            .article-navigation {
                gap: 10px;
            }

            .nav-btn {
                padding: 10px 12px;
                font-size: 14px;
            }

            /* 确保按钮文字不会太长 */
            .nav-btn span {
                display: -webkit-box;
                -webkit-line-clamp: 1;
                line-clamp: 1;
                -webkit-box-orient: vertical;
                overflow: hidden;
                text-overflow: ellipsis;
            }

            /* 小屏幕下调整图标大小 */
            .nav-btn i {
                font-size: 12px;
            }
        }

        @media (max-height: 500px) and (orientation: landscape) {
            .navbar {
                padding: 8px 0;
            }

            .main-content {
                padding: 16px 0;
            }

            .article-content {
                padding: 16px;
            }
        }

        /* 确保代码块在移动端不会溢出 */
        pre code {
            white-space: pre;
            word-wrap: normal;
        }
    </style>
</head>

<body class="light-theme">
    <!-- 阅读进度条 -->
    <div class="reading-progress">
        <div class="reading-progress-bar" id="progressBar"></div>
    </div>

    <header>
        <div class="container">
            <nav class="navbar">
                <a href="index.html" class="logo">
                    <i class="fas fa-code"></i>
                    TechBlog
                </a>

                <div class="nav-links">
                    <a href="index.html">首页</a>
                    <a href="article-list.html">文章</a>
                    <a href="tutorial-list.html">教程</a>
                    <a href="projects.html">项目</a>
                    <a href="about.html">关于</a>
                </div>

                <div class="nav-actions">
                    <button class="theme-toggle" id="themeToggle">
                        <i class="fas fa-moon"></i>
                        <span>深色模式</span>
                    </button>
                    <button class="mobile-menu" id="mobileMenu">
                        <i class="fas fa-bars"></i>
                    </button>
                </div>
            </nav>
        </div>
    </header>

    <div class="container">
        <div class="main-content">
            <!-- 文章头部 -->
            <div class="article-header">
                <h1 class="article-title">深入理解React Hooks的工作原理</h1>
                <div class="article-meta">
                    <span><i class="far fa-calendar"></i> 2023-10-15</span>
                    <span><i class="far fa-clock"></i> 8分钟阅读</span>
                    <span><i class="far fa-eye"></i> 1.2k浏览</span>
                    <span><i class="far fa-user"></i> 张明</span>
                </div>
                <div class="article-tags">
                    <span class="tag">React</span>
                    <span class="tag">JavaScript</span>
                    <span class="tag">前端</span>
                    <span class="tag">Hooks</span>
                </div>
            </div>

            <!-- 文章操作栏 -->
            <div class="article-actions">
                <div class="action-buttons">
                    <button class="action-btn" id="likeBtn">
                        <i class="far fa-thumbs-up"></i> 点赞
                    </button>
                    <button class="action-btn" id="bookmarkBtn">
                        <i class="far fa-bookmark"></i> 收藏
                    </button>
                </div>
                <div class="share-options">
                    <button class="share-btn" title="分享到Twitter">
                        <i class="fab fa-twitter"></i>
                    </button>
                    <button class="share-btn" title="分享到LinkedIn">
                        <i class="fab fa-linkedin-in"></i>
                    </button>
                    <button class="share-btn" title="复制链接">
                        <i class="fas fa-link"></i>
                    </button>
                </div>
            </div>

            <!-- 内容区域和目录 -->
            <div class="content-container">
                <!-- 文章内容 -->
                <article class="article-content">
                    <div class="article-body">
                        <p>React Hooks 是 React 16.8 引入的一项重要特性，它允许我们在函数组件中使用状态和其他 React 特性。本文将深入探讨 React Hooks 的内部实现机制，包括
                            useState、useEffect 等常用 Hook 的工作原理，以及如何避免常见的性能陷阱。</p>

                        <h2 id="hooks-intro">Hooks 的基本概念</h2>
                        <p>在 Hooks 出现之前，函数组件通常被认为是无状态的，只能通过 props 接收数据并渲染 UI。如果需要状态或生命周期方法，就必须使用类组件。Hooks
                            的引入改变了这一现状，使得函数组件能够拥有和类组件相似的能力。</p>

                        <p>Hooks 的设计遵循以下几个原则：</p>
                        <ul>
                            <li>只在最顶层使用 Hooks，不要在循环、条件或嵌套函数中调用</li>
                            <li>只在 React 函数组件或自定义 Hooks 中调用 Hooks</li>
                            <li>Hooks 的调用顺序在每次渲染中必须保持一致</li>
                        </ul>

                        <h2 id="useState-hook">useState Hook 的工作原理</h2>
                        <p>useState 是最基本的 Hook，它允许我们在函数组件中添加状态。下面是一个简单的示例：</p>

                        <pre><code class="language-javascript">import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    &lt;div&gt;
      &lt;p&gt;You clicked {count} times&lt;/p&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
        Click me
      &lt;/button&gt;
    &lt;/div&gt;
  );
}</code></pre>

                        <p>在内部，React 为每个组件维护了一个"记忆单元格"列表，这些单元格是简单的 JavaScript 对象，用于存储 Hook 的状态。当组件首次渲染时，React 会为每个
                            useState 调用创建一个新的状态单元格。</p>

                        <p>在后续的重新渲染中，React 会按照 Hooks 的调用顺序来读取这些状态值。这就是为什么 Hooks 的调用顺序必须保持一致的原因 - React 依赖于调用顺序来将状态与特定的
                            Hook 关联起来。</p>

                        <h3 id="useState-implementation">useState 的简化实现</h3>
                        <p>为了更好地理解 useState 的工作原理，我们可以看一下它的简化实现：</p>

                        <pre><code class="language-javascript">let currentHook = 0;
let hooks = [];

function useState(initialValue) {
  const hookIndex = currentHook;
  currentHook++;
  
  if (hooks[hookIndex] === undefined) {
    hooks[hookIndex] = initialValue;
  }
  
  const setState = (newValue) => {
    hooks[hookIndex] = newValue;
    // 触发重新渲染
    render();
  };
  
  return [hooks[hookIndex], setState];
}

// 在每次渲染前重置 currentHook
function render() {
  currentHook = 0;
  // ... 执行组件渲染逻辑
}</code></pre>

                        <p>这个简化版本展示了 React 如何通过维护一个 Hook 数组和当前 Hook 索引来跟踪状态。实际的 React 实现要复杂得多，但基本思想是相似的。</p>

                        <h2 id="useEffect-hook">useEffect Hook 的工作原理</h2>
                        <p>useEffect Hook 允许我们在函数组件中执行副作用操作，类似于类组件中的 componentDidMount、componentDidUpdate 和
                            componentWillUnmount 的组合。</p>

                        <pre><code class="language-javascript">import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]); // 仅在 count 更改时更新

  return (
    &lt;div&gt;
      &lt;p&gt;You clicked {count} times&lt;/p&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
        Click me
      &lt;/button&gt;
    &lt;/div&gt;
  );
}</code></pre>

                        <p>useEffect 的工作原理可以概括为以下几个步骤：</p>
                        <ol>
                            <li>在组件渲染完成后，React 会执行 useEffect 中的函数</li>
                            <li>如果提供了依赖数组，React 会比较当前依赖和上一次的依赖</li>
                            <li>如果依赖发生变化，或者没有提供依赖数组，effect 会在每次渲染后执行</li>
                            <li>如果 effect 返回一个清理函数，这个函数会在组件卸载或下一次 effect 执行前调用</li>
                        </ol>

                        <h3 id="useEffect-implementation">useEffect 的简化实现</h3>
                        <p>下面是一个 useEffect 的简化实现，帮助我们理解其内部机制：</p>

                        <pre><code class="language-javascript">let currentEffect = 0;
let effects = [];

function useEffect(callback, dependencies) {
  const effectIndex = currentEffect;
  currentEffect++;
  
  const hasNoDependencies = !dependencies;
  const oldDependencies = effects[effectIndex];
  const hasChangedDependencies = oldDependencies 
    ? dependencies.some((dep, i) => !Object.is(dep, oldDependencies[i]))
    : true;
  
  if (hasNoDependencies || hasChangedDependencies) {
    effects[effectIndex] = dependencies;
    
    // 清理上一次的 effect
    if (effects[effectIndex].cleanup) {
      effects[effectIndex].cleanup();
    }
    
    // 执行新的 effect 并存储清理函数
    effects[effectIndex].cleanup = callback();
  }
}</code></pre>

                        <h2 id="hooks-rules">Hooks 规则与最佳实践</h2>
                        <p>为了确保 Hooks 正常工作，我们需要遵循一些规则和最佳实践：</p>

                        <h3 id="rule-1">1. 只在最顶层调用 Hooks</h3>
                        <p>不要在循环、条件或嵌套函数中调用 Hooks。这是因为 React 依赖于 Hooks 的调用顺序来正确关联状态和 effect。</p>

                        <pre><code class="language-javascript">// ✅ 正确：在组件顶层调用
function MyComponent() {
  const [name, setName] = useState('Mary');
  const [age, setAge] = useState(30);
  
  useEffect(() => {
    // ...
  });
  
  // ...
}

// ❌ 错误：在条件中调用
function MyComponent({ isVisible }) {
  if (isVisible) {
    const [name, setName] = useState('Mary'); // 错误！
  }
  
  // ...
}</code></pre>

                        <h3 id="rule-2">2. 只在 React 函数中调用 Hooks</h3>
                        <p>不要在普通的 JavaScript 函数中调用 Hooks。只能在 React 函数组件或自定义 Hooks 中调用。</p>

                        <h3 id="optimization">3. 性能优化</h3>
                        <p>使用 useCallback 和 useMemo 来避免不必要的重新渲染：</p>

                        <pre><code class="language-javascript">function MyComponent({ items }) {
  const [filter, setFilter] = useState('');
  
  // 使用 useMemo 缓存计算结果
  const filteredItems = useMemo(() => {
    return items.filter(item => item.name.includes(filter));
  }, [items, filter]);
  
  // 使用 useCallback 缓存函数
  const handleClick = useCallback(() => {
    // 处理点击事件
  }, [filter]);
  
  return (
    // ...
  );
}</code></pre>

                        <h2 id="custom-hooks">自定义 Hooks</h2>
                        <p>自定义 Hooks 是一种重用状态逻辑的机制。它们本质上是普通的 JavaScript 函数，但其名称以 "use" 开头，并且可以调用其他 Hooks。</p>

                        <pre><code class="language-javascript">// 自定义 Hook：用于跟踪窗口大小
function useWindowSize() {
  const [size, setSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight
  });
  
  useEffect(() => {
    const handleResize = () => {
      setSize({
        width: window.innerWidth,
        height: window.innerHeight
      });
    };
    
    window.addEventListener('resize', handleResize);
    
    // 清理函数
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);
  
  return size;
}

// 在组件中使用自定义 Hook
function MyComponent() {
  const size = useWindowSize();
  
  return (
    &lt;div&gt;
      Window size: {size.width} x {size.height}
    &lt;/div&gt;
  );
}</code></pre>

                        <h2 id="conclusion">总结</h2>
                        <p>React Hooks 通过维护一个 Hook 调用顺序的链表来工作，这使得函数组件能够拥有状态和生命周期等特性。理解 Hooks 的内部机制有助于我们更好地使用它们，并避免常见的陷阱。
                        </p>

                        <p>随着 React 的不断发展，Hooks 已经成为构建 React 应用的标准方式。掌握 Hooks 不仅意味着能够编写更简洁的代码，还意味着能够更好地理解 React 的工作原理。
                        </p>

                        <p>希望本文能够帮助你更深入地理解 React Hooks，并在实际开发中更加自信地使用它们。</p>
                    </div>

                    <!-- 文章导航 -->
                    <div class="article-navigation">
                        <a href="#" class="nav-btn prev">
                            <i class="fas fa-arrow-left"></i>
                            <span>上一篇：React组件设计模式与实践</span>
                        </a>
                        <a href="#" class="nav-btn next">
                            <span>下一篇：React性能优化完全指南</span>
                            <i class="fas fa-arrow-right"></i>
                        </a>
                    </div>
                </article>

                <!-- 目录 -->
                <aside class="toc-container">
                    <div class="toc-card">
                        <h3 class="toc-title">目录</h3>
                        <ul class="toc-list">
                            <li class="toc-item">
                                <a href="#hooks-intro" class="toc-link">Hooks 的基本概念</a>
                            </li>
                            <li class="toc-item">
                                <a href="#useState-hook" class="toc-link">useState Hook 的工作原理</a>
                                <ul class="toc-sublist">
                                    <li class="toc-item">
                                        <a href="#useState-implementation" class="toc-link">useState 的简化实现</a>
                                    </li>
                                </ul>
                            </li>
                            <li class="toc-item">
                                <a href="#useEffect-hook" class="toc-link">useEffect Hook 的工作原理</a>
                                <ul class="toc-sublist">
                                    <li class="toc-item">
                                        <a href="#useEffect-implementation" class="toc-link">useEffect 的简化实现</a>
                                    </li>
                                </ul>
                            </li>
                            <li class="toc-item">
                                <a href="#hooks-rules" class="toc-link">Hooks 规则与最佳实践</a>
                                <ul class="toc-sublist">
                                    <li class="toc-item">
                                        <a href="#rule-1" class="toc-link">1. 只在最顶层调用 Hooks</a>
                                    </li>
                                    <li class="toc-item">
                                        <a href="#rule-2" class="toc-link">2. 只在 React 函数中调用 Hooks</a>
                                    </li>
                                    <li class="toc-item">
                                        <a href="#optimization" class="toc-link">3. 性能优化</a>
                                    </li>
                                </ul>
                            </li>
                            <li class="toc-item">
                                <a href="#custom-hooks" class="toc-link">自定义 Hooks</a>
                            </li>
                            <li class="toc-item">
                                <a href="#conclusion" class="toc-link">总结</a>
                            </li>
                        </ul>
                    </div>
                </aside>
            </div>

            <!-- 相关文章 -->
            <div class="related-articles">
                <h3 class="section-title">相关文章</h3>
                <div class="related-grid">
                    <div class="related-card">
                        <h4 class="related-title"><a href="#">React组件设计模式与实践</a></h4>
                        <div class="related-meta">
                            <span><i class="far fa-calendar"></i> 2023-09-20</span>
                            <span><i class="far fa-clock"></i> 6分钟阅读</span>
                        </div>
                        <p class="related-excerpt">探索React组件设计的最佳实践，包括高阶组件、渲染属性等模式。</p>
                    </div>
                    <div class="related-card">
                        <h4 class="related-title"><a href="#">React性能优化完全指南</a></h4>
                        <div class="related-meta">
                            <span><i class="far fa-calendar"></i> 2023-08-15</span>
                            <span><i class="far fa-clock"></i> 10分钟阅读</span>
                        </div>
                        <p class="related-excerpt">深入探讨React应用性能优化的各种技术和工具，帮助你构建更快的应用。</p>
                    </div>
                    <div class="related-card">
                        <h4 class="related-title"><a href="#">TypeScript与React集成指南</a></h4>
                        <div class="related-meta">
                            <span><i class="far fa-calendar"></i> 2023-07-10</span>
                            <span><i class="far fa-clock"></i> 7分钟阅读</span>
                        </div>
                        <p class="related-excerpt">学习如何在React项目中有效使用TypeScript，提高代码质量和开发效率。</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <footer>
        <div class="container">
            <p>© 2023 TechBlog - 探索技术的无限可能</p>
        </div>
    </footer>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
    <script>
        // 初始化代码高亮
        hljs.highlightAll();

        // 主题切换功能
        const themeToggle = document.getElementById('themeToggle');
        const body = document.body;

        themeToggle.addEventListener('click', () => {
            if (body.classList.contains('light-theme')) {
                body.classList.remove('light-theme');
                body.classList.add('dark-theme');
                themeToggle.innerHTML = '<i class="fas fa-sun"></i><span>浅色模式</span>';
                localStorage.setItem('theme', 'dark');
            } else {
                body.classList.remove('dark-theme');
                body.classList.add('light-theme');
                themeToggle.innerHTML = '<i class="fas fa-moon"></i><span>深色模式</span>';
                localStorage.setItem('theme', 'light');
            }
        });

        // 检查本地存储的主题设置
        const savedTheme = localStorage.getItem('theme');
        if (savedTheme === 'dark') {
            body.classList.remove('light-theme');
            body.classList.add('dark-theme');
            themeToggle.innerHTML = '<i class="fas fa-sun"></i><span>浅色模式</span>';
        }

        // 移动端菜单切换
        const mobileMenu = document.getElementById('mobileMenu');
        const navLinks = document.querySelector('.nav-links');

        mobileMenu.addEventListener('click', () => {
            navLinks.classList.toggle('active');
        });

        // 点击页面其他区域关闭移动菜单
        document.addEventListener('click', (e) => {
            if (!e.target.closest('.nav-actions') && !e.target.closest('.nav-links')) {
                navLinks.classList.remove('active');
            }
        });

        // 阅读进度条
        window.addEventListener('scroll', () => {
            const winHeight = window.innerHeight;
            const docHeight = document.documentElement.scrollHeight;
            const scrollTop = window.pageYOffset;
            const scrollPercent = (scrollTop) / (docHeight - winHeight) * 100;
            const progressBar = document.getElementById('progressBar');
            progressBar.style.width = scrollPercent + '%';
        });

        // 目录高亮功能 - 修复版本
        document.addEventListener('DOMContentLoaded', function () {
            const sections = document.querySelectorAll('h2, h3');
            const tocLinks = document.querySelectorAll('.toc-link');
            const headerHeight = document.querySelector('header').offsetHeight + 20;

            // 添加滚动监听（使用防抖优化性能）
            let scrollTimeout;
            window.addEventListener('scroll', function () {
                clearTimeout(scrollTimeout);
                scrollTimeout = setTimeout(highlightTOC, 10);
            });

            function highlightTOC() {
                let currentSection = '';
                let maxVisibleArea = 0;

                // 遍历所有章节标题，找到最可见的章节
                sections.forEach(section => {
                    const rect = section.getBoundingClientRect();
                    const sectionTop = rect.top;
                    const sectionHeight = rect.height;

                    // 计算章节在可视区域内的可见面积
                    const visibleTop = Math.max(0, sectionTop);
                    const visibleBottom = Math.min(window.innerHeight, sectionTop + sectionHeight);
                    const visibleHeight = Math.max(0, visibleBottom - visibleTop);
                    const visibleArea = visibleHeight / sectionHeight;

                    // 如果章节在可视区域内且可见面积最大，则设为当前章节
                    if (sectionTop < window.innerHeight &&
                        sectionTop + sectionHeight > 0 &&
                        visibleArea > maxVisibleArea) {
                        maxVisibleArea = visibleArea;
                        currentSection = section.id;
                    }
                });

                // 如果没有找到合适的章节，使用第一个可见的章节
                if (!currentSection) {
                    sections.forEach(section => {
                        const rect = section.getBoundingClientRect();
                        if (rect.top < window.innerHeight && rect.bottom > 0 && !currentSection) {
                            currentSection = section.id;
                        }
                    });
                }

                // 更新目录高亮
                tocLinks.forEach(link => {
                    link.classList.remove('active');

                    if (link.getAttribute('href') === '#' + currentSection) {
                        link.classList.add('active');

                        // 滚动到当前激活的目录项（可选）
                        const tocContainer = document.querySelector('.toc-container');
                        const activeLink = document.querySelector('.toc-link.active');

                        if (activeLink && tocContainer) {
                            const containerHeight = tocContainer.offsetHeight;
                            const linkTop = activeLink.offsetTop;
                            const linkHeight = activeLink.offsetHeight;

                            // 确保激活的目录项在可视区域内
                            if (linkTop < tocContainer.scrollTop ||
                                linkTop + linkHeight > tocContainer.scrollTop + containerHeight) {
                                tocContainer.scrollTop = linkTop - containerHeight / 3;
                            }
                        }
                    }
                });
            }

            // 初始高亮
            highlightTOC();

            // 平滑滚动到锚点
            tocLinks.forEach(link => {
                link.addEventListener('click', function (e) {
                    e.preventDefault();

                    const targetId = this.getAttribute('href').substring(1);
                    const targetElement = document.getElementById(targetId);

                    if (targetElement) {
                        const targetPosition = targetElement.offsetTop - headerHeight;

                        window.scrollTo({
                            top: targetPosition,
                            behavior: 'smooth'
                        });
                    }
                });
            });

            // 点赞和收藏功能
            const likeBtn = document.getElementById('likeBtn');
            const bookmarkBtn = document.getElementById('bookmarkBtn');

            likeBtn.addEventListener('click', function () {
                this.classList.toggle('liked');
                if (this.classList.contains('liked')) {
                    this.innerHTML = '<i class="fas fa-thumbs-up"></i> 已点赞';
                    localStorage.setItem('liked', 'true');
                } else {
                    this.innerHTML = '<i class="far fa-thumbs-up"></i> 点赞';
                    localStorage.setItem('liked', 'false');
                }
            });

            bookmarkBtn.addEventListener('click', function () {
                this.classList.toggle('bookmarked');
                if (this.classList.contains('bookmarked')) {
                    this.innerHTML = '<i class="fas fa-bookmark"></i> 已收藏';
                    localStorage.setItem('bookmarked', 'true');
                } else {
                    this.innerHTML = '<i class="far fa-bookmark"></i> 收藏';
                    localStorage.setItem('bookmarked', 'false');
                }
            });

            // 检查本地存储的点赞和收藏状态
            if (localStorage.getItem('liked') === 'true') {
                likeBtn.classList.add('liked');
                likeBtn.innerHTML = '<i class="fas fa-thumbs-up"></i> 已点赞';
            }

            if (localStorage.getItem('bookmarked') === 'true') {
                bookmarkBtn.classList.add('bookmarked');
                bookmarkBtn.innerHTML = '<i class="fas fa-bookmark"></i> 已收藏';
            }

            // 分享功能
            const shareButtons = document.querySelectorAll('.share-btn');

            shareButtons.forEach(button => {
                button.addEventListener('click', function () {
                    const title = document.title;
                    const url = window.location.href;

                    if (this.querySelector('.fa-twitter')) {
                        // 分享到Twitter
                        window.open(`https://twitter.com/intent/tweet?text=${encodeURIComponent(title)}&url=${encodeURIComponent(url)}`, '_blank');
                    } else if (this.querySelector('.fa-linkedin-in')) {
                        // 分享到LinkedIn
                        window.open(`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`, '_blank');
                    } else if (this.querySelector('.fa-link')) {
                        // 复制链接
                        navigator.clipboard.writeText(url).then(() => {
                            const originalHTML = this.innerHTML;
                            this.innerHTML = '<i class="fas fa-check"></i>';
                            setTimeout(() => {
                                this.innerHTML = originalHTML;
                            }, 2000);
                        });
                    }
                });
            });
        });
    </script>
</body>

</html>